package com.imooc.o2o.util;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.imageio.ImageIO;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.imooc.o2o.dto.ImageHolder;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

/**
 * 图片处理类
 * spring会将前台上传上来的文件用一个MultipartFile接口来处理，而这个接口有一个实现类CommonsMultipartFile
 * CommonsMultipartFile转换成java.io.File类型是可以的，因为CommonsMultipartFile类里面提供了方法，但是从File转换成
 * CommonsMultipartFile就比较困难
 * @author ASUS
 *
 */
public class ImageUtil {
	//获取classpath
	private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
	private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
	private static final Random random = new Random();
	private static Logger logger = LoggerFactory.getLogger(ImageUtil.class);
	
	
	/**
	 * 将CommonsMultipartFile转换成File类
	 * @param cFile
	 * @return
	 */
	public static File transferCommonsMultipartFileToFile(CommonsMultipartFile cFile) {
		File newFile = new File(cFile.getOriginalFilename());
		try {
			cFile.transferTo(newFile);
		} catch (IllegalStateException e) {
			logger.error(e.toString());
			e.printStackTrace();
		} catch (IOException e) {
			logger.error(e.toString());
			e.printStackTrace();
		}
		return newFile;
	}
	
	
	/**
	 * 处理缩略图，返回新生成图片路径的相对值路径，用于存进数据库
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateThumbnail(ImageHolder thumbnail,String targetAddr) {
		//获取文件的随机名
		String realFileName = getRandomFileName();
		//获取用户上传的文件图片的扩展名
		String extension = getFileExtension(thumbnail.getImageName());
		//随即名和扩展名加起来获取就共同构成了新文件的名字
		//targetAddr是新文件的存储路径
		makeDirPath(targetAddr);
		//获取图片的相对路径
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is" + relativeAddr);
		//根路径和相对路径组成图片的全路径
		File dest = new File(PathUtil.getImgBasePath()+relativeAddr);
		logger.debug("current completeAddr is" + PathUtil.getImgBasePath()+relativeAddr);
		try {
			Thumbnails.of(thumbnail.getImage()).size(200, 200)
			.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath+"/watermark.jpg")), 0.25f)
			.outputQuality(0.8f).toFile(dest);
		}catch(IOException e) {
			logger.error(e.toString());
			e.printStackTrace();
		}
		return relativeAddr;
	}
	
	/**
	 * 创建目标目录所涉及到的目录，即/home/jiange/xxx.jpg,那么home jiange这两个文件夹都得自动创建
	 * @param targetAddr
	 */
	private static void makeDirPath(String targetAddr) {
		String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
		File dirPath = new File(realFileParentPath);
		if(!dirPath.exists()) {
			dirPath.mkdirs();
		}
		
	}

	/**
	 * 获取输入文件流的扩展名
	 * @param thumbnail
	 * @return
	 */
	private static String getFileExtension(String fileName) {
		return fileName.substring(fileName.lastIndexOf("."));
	}
	/**
	 * 生成随机文件名，当前年月日时分秒+五位随机数
	 * @return
	 */
	public static String getRandomFileName() {
		//获取随机的五位数(10000-99999)
		 int randnum = random.nextInt(89999) + 10000;
		 String nowTimeStr = sDateFormat.format(new Date());
		return nowTimeStr + randnum;
	}

	public static void main(String[] args) throws IOException {
		//of函数用来传入相关的要处理的图片或者图片流,siez函数用来指定输出图片的指定大小,watermark函数给要输出的图片添加水印
		//watermark函数的三个参数，水印图片要加在的位置，水印图片的来源，透明度。
		//outputQuality函数用于压缩，参数为压缩比
		Thumbnails.of(new File("D:/campusdevelop/xiaohuangren.jpg"))
		.size(200, 200).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath+"/watermark.jpg")), 0.25f)
		.outputQuality(0.8f).toFile("D:/campusdevelop/xiaohuangrennew.jpg");
	}
	
	/**
	 * storePath是文件的路径还是目录的路径
	 * 如果storePath是文件的路径就删除该文件，
	 * 如果storePath是目录的路径，就删除该目录下的所有文件
	 * @param storePath
	 */
	public static void deleteFileOrPath(String storePath) {
		File fileOrPath = new File(PathUtil.getImgBasePath()+storePath);
		if(fileOrPath.exists()) {
			if(fileOrPath.isDirectory()) {
				File files[] = fileOrPath.listFiles();
				for(int i=0;i<files.length;i++) {
					files[i].delete();
				}
			}
			fileOrPath.delete();
		}
	}
	
	/**
	 * 处理详情图，并返回新生成图片的相对值路径
	 * 
	 * @param thumbnail
	 * @param targetAddr
	 * @return
	 */
	public static String generateNormalImg(ImageHolder thumbnail, String targetAddr) {
		// 获取不重复的随机名
		String realFileName = getRandomFileName();
		// 获取文件的扩展名如png,jpg等
		String extension = getFileExtension(thumbnail.getImageName());
		// 如果目标路径不存在，则自动创建
		makeDirPath(targetAddr);
		// 获取文件存储的相对路径(带文件名)
		String relativeAddr = targetAddr + realFileName + extension;
		logger.debug("current relativeAddr is :" + relativeAddr);
		// 获取文件要保存到的目标路径
		File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
		logger.debug("current complete addr is :" + PathUtil.getImgBasePath() + relativeAddr);
		// 调用Thumbnails生成带有水印的图片
		try {
			Thumbnails.of(thumbnail.getImage()).size(337, 640)
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/watermark.jpg")), 0.25f)
					.outputQuality(0.9f).toFile(dest);
		} catch (IOException e) {
			logger.error(e.toString());
			throw new RuntimeException("创建缩图片失败：" + e.toString());
		}
		// 返回图片相对路径地址
		return relativeAddr;
	}
}
